//package com.kingwang.study.spring.security.demo.security.config;
//
//import com.kingwang.study.spring.security.demo.security.constant.SecurityConstants;
//import com.kingwang.study.spring.security.demo.security.filter.TokenBasedAuthenticationFilter;
//import com.kingwang.study.spring.security.demo.security.handler.JsonResponseAuthenticationFailureHandler;
//import com.kingwang.study.spring.security.demo.security.handler.JsonResponseAuthenticationSuccessHandler;
//import com.kingwang.study.spring.security.demo.security.handler.SystemLogoutHandler;
//import com.kingwang.study.spring.security.demo.security.provider.TokenBasedAuthenticationProvider;
//import com.kingwang.study.spring.security.demo.security.repository.HttpTokenSecurityContextRepository;
//import com.kingwang.study.spring.security.demo.security.token.session.TokenSessionManager;
//import com.kingwang.study.spring.security.demo.util.HttpServletUtils;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.http.HttpStatus;
//import org.springframework.security.authentication.AuthenticationProvider;
//import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
//import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
//import org.springframework.security.config.annotation.web.builders.HttpSecurity;
//import org.springframework.security.config.annotation.web.builders.WebSecurity;
//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
//import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
//import org.springframework.security.config.http.SessionCreationPolicy;
//import org.springframework.security.core.userdetails.UserDetailsService;
//import org.springframework.security.crypto.password.PasswordEncoder;
//import org.springframework.security.web.authentication.AuthenticationFailureHandler;
//import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
//import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
//import org.springframework.security.web.authentication.logout.LogoutFilter;
//import org.springframework.security.web.context.SecurityContextRepository;
//
//import javax.annotation.Resource;
//
//@Configuration
//@EnableWebSecurity
//@EnableGlobalMethodSecurity(prePostEnabled = true)
//public class TokenOnlySecurityConfig extends WebSecurityConfigurerAdapter {
//    /**
//     * 拦截的URL
//     */
//    public static final String URL_LOGIN_TOKEN = SecurityConstants.URL_LOGIN_TOKEN;
//
//    /**
//     * 登出处理器
//     */
//    @Resource
//    private SystemLogoutHandler systemLogoutHandler;
//
//    /**
//     * 用户信息获取服务
//     */
//    @Resource
//    private UserDetailsService userDetailsService;
//
//    /**
//     * 密码加密
//     */
//    @Resource
//    private PasswordEncoder passwordEncoder;
//
//    /**
//     * Token会话管理器
//     */
//    @Resource
//    private TokenSessionManager tokenSessionManager;
//
//
//    /**
//     * 初始化方法
//     *
//     * @param web
//     * @throws Exception
//     */
//    @Override
//    public void init(WebSecurity web) throws Exception {
//        super.init(web);
//
//        HttpSecurity http = getHttp();
//
//        http.setSharedObject(SecurityContextRepository.class, new HttpTokenSecurityContextRepository(this.tokenSessionManager));
//    }
//
//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//        http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
//                    // 未提供登录凭据返回HTTP 401
//                    HttpServletUtils.sendHttpStatusResponse(response, HttpStatus.UNAUTHORIZED);
//                })
//                .and()
//                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
//                .and()
//                .formLogin().disable()
//                // 这样配置AuthenticationProvider是无效的
//                // .authenticationProvider(tokenBasedAuthenticationProvider())
//                .cors()
//                .and()
//                .csrf().disable()
//                .httpBasic().disable()
//                .anonymous().disable()
//                .addFilterAfter(tokenBasedAuthenticationFilter(), LogoutFilter.class)
//                .authorizeRequests()
//                .antMatchers(URL_LOGIN_TOKEN).permitAll()
//                .anyRequest().authenticated()
//                .and()
//                .logout()
//                /**
//                 * 自定义登录处理器，处理Session和Token失效
//                 */
//                .addLogoutHandler(this.systemLogoutHandler)
//                /**
//                 * 登录成功后返回HTTP 200
//                 */
//                .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler());
//    }
//
//    /**
//     * 必须使用这个方法配置AuthenticationProvider
//     *
//     * @param auth
//     * @throws Exception
//     */
//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.authenticationProvider(tokenBasedAuthenticationProvider());
//    }
//
//    /**
//     * 自定义TokenBasedAuthenticationFilter
//     *
//     * @return
//     * @throws Exception
//     */
//    private TokenBasedAuthenticationFilter tokenBasedAuthenticationFilter() throws Exception {
//        TokenBasedAuthenticationFilter result = new TokenBasedAuthenticationFilter();
//
//        result.setAuthenticationManager(authenticationManager());
//        /**
//         * Token认证登录成功和失败后返回JSON
//         */
//        result.setAuthenticationSuccessHandler(jsonResponseAuthenticationSuccessHandler());
//        result.setAuthenticationFailureHandler(jsonResponseAuthenticationFailureHandler());
//
//        return result;
//    }
//
//    private AuthenticationSuccessHandler jsonResponseAuthenticationSuccessHandler() {
//        return new JsonResponseAuthenticationSuccessHandler();
//    }
//
//    private AuthenticationFailureHandler jsonResponseAuthenticationFailureHandler() {
//        return new JsonResponseAuthenticationFailureHandler();
//    }
//
//    @Override
//    protected UserDetailsService userDetailsService() {
//        return this.userDetailsService;
//    }
//
//    private AuthenticationProvider tokenBasedAuthenticationProvider() {
//        TokenBasedAuthenticationProvider result = new TokenBasedAuthenticationProvider();
//
//        result.setUserDetailsService(this.userDetailsService);
//        result.setPasswordEncoder(this.passwordEncoder);
//        result.setTokenSessionManager(this.tokenSessionManager);
//
//        return result;
//    }
//}
